package com.ysd.lis.service.lab.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.DeleteJoinWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ysd.common.Result;
import com.ysd.lis.entity.lab.*;
import com.ysd.lis.mapper.lab.LabFeeItemMapper;
import com.ysd.lis.mapper.lab.LabFeeitemVsItemDictMapper;
import com.ysd.lis.request.AddFeeItemParam;
import com.ysd.lis.request.ExtenFieldsValueDataResponseDto;
import com.ysd.lis.request.ExtenFieldsValuePageRequestDto;
import com.ysd.lis.request.FeeItemPageParam;
import com.ysd.lis.service.SysExtenFieldsValueService;
import com.ysd.lis.service.lab.LabFeeItemService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author LiuQi
 * @since 2023-12-09
 */
@Service
public class LabFeeItemServiceImpl extends ServiceImpl<LabFeeItemMapper, LabFeeItem> implements LabFeeItemService {

    @Autowired
    private LabFeeItemMapper labFeeItemMapper;

    @Autowired
    private SysExtenFieldsValueService sysExtenFieldsValueService;

    @Override
    public Result findLabApplyItemList(FeeItemPageParam feeItemPageParam) {
        MPJLambdaWrapper<LabFeeItem> lambdaQueryWrapper = new MPJLambdaWrapper<>();

        lambdaQueryWrapper.selectAll(LabFeeItem.class);
//            .leftJoin(LabFeeitemVsBarcode.class, "b", LabFeeitemVsBarcode::getFeeId, LabFeeItem::getId)
//                .leftJoin(LabRptVsBarcode.class, "c", LabRptVsBarcode::getBarcodeId, LabFeeitemVsBarcode::getBarcodeId)
//                .eq(StrUtil.isNotEmpty(feeItemPageParam.getGroupId()),  LabRptVsBarcode::getRptGroupId,feeItemPageParam.getGroupId());

        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(feeItemPageParam.getOrgId()), LabFeeItem::getOrgId, feeItemPageParam.getOrgId()).eq(LabFeeItem::getDelFlag, 0);
        if (StrUtil.isNotEmpty(feeItemPageParam.getKeyWords())) {
            lambdaQueryWrapper.and(wrapper ->
                    wrapper.like(LabFeeItem::getFeeCode, feeItemPageParam.getKeyWords())
                            .or()
                            .like(LabFeeItem::getFeeName, feeItemPageParam.getKeyWords())
                            .or()
                            .like(LabFeeItem::getInputCode, feeItemPageParam.getKeyWords())
            );
        }
        if (StrUtil.isNotEmpty(feeItemPageParam.getBarcodeNo())) {
            StringBuffer existsSql = new StringBuffer("SELECT 1 FROM LAB_FEEITEM_VS_BARCODE t2 WHERE t.FEE_CODE = t2.FEE_CODE");// AND t2.BARCODE_NO = '" + feeItemPageParam.getBarcodeNo() + "' ");
            lambdaQueryWrapper.notExists(existsSql.toString());
        }
        if (StrUtil.isNotEmpty(feeItemPageParam.getSampleTypeId()) && StrUtil.isNotEmpty(feeItemPageParam.getPurposeId())) {
            StringBuffer existsSql = new StringBuffer("SELECT 1 FROM BAC_REQPURPOSE_VS_FEEITEM t2 WHERE t2.DEL_FLAG=0 and t.FEE_CODE = t2.FEE_CODE AND t2.PURPOSE_NO = '" + feeItemPageParam.getPurposeId() + "' AND t2.SAMPLE_TYPE_CODE = '" + feeItemPageParam.getSampleTypeId() + "' ");
            lambdaQueryWrapper.notExists(existsSql.toString());
        }
        if (StrUtil.isNotEmpty(feeItemPageParam.getCompanyCode())) {
            StringBuffer existsSql = new StringBuffer("SELECT 1 FROM LAB_INSPECT_COMPANY_FEEITEM t2 WHERE t2.DEL_FLAG=0 and t.FEE_CODE = t2.FEE_CODE AND t2.COMPANY_CODE = '"+feeItemPageParam.getCompanyCode()+"'");// AND t2.BARCODE_NO = '" + feeItemPageParam.getBarcodeNo() + "' ");
            lambdaQueryWrapper.notExists(existsSql.toString());
        }
        //lambdaQueryWrapper.eq(StringUtils.isNotBlank(feeItemPageParam.getOrgId()), LabFeeItem::getOrgId, feeItemPageParam.getOrgId());
        List<LabFeeItem> labFeeItems = labFeeItemMapper.selectList(lambdaQueryWrapper);

        //查询报告单元下得申请项目与报告项目关联数据
        if (StrUtil.isNotEmpty(feeItemPageParam.getRptGroup())) {
            List<String> feeItemCodes = labFeeItems.stream().map(LabFeeItem::getFeeCode).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(feeItemCodes)) {
                MPJLambdaWrapper<LabFeeitemVsItemDict> queryWrapper = new MPJLambdaWrapper<>();
                queryWrapper
                        .selectCount(LabFeeitemVsItemDict::getFeeCode, LabFeeItem::getFeeiVsDictCnt)
                        .selectAs(LabFeeitemVsItemDict::getFeeCode, LabFeeItem::getFeeCode)
                        .eq(LabFeeitemVsItemDict::getRptGroup, feeItemPageParam.getRptGroup())
                        .in(LabFeeitemVsItemDict::getFeeCode, feeItemCodes)
                        .eq(LabFeeitemVsItemDict::getDelFlag, 0)
                        .groupBy(LabFeeitemVsItemDict::getFeeCode);
                //根据报告单元与申请项目查询关联数据
                List<LabFeeItem> labFeeitemVsItemDictCntList = labFeeitemVsItemDictMapper.selectJoinList(LabFeeItem.class, queryWrapper);
                for (LabFeeItem feeItem : labFeeItems) {
                    Optional<LabFeeItem> first = labFeeitemVsItemDictCntList.stream().filter(cnt -> cnt.getFeeCode().equals(feeItem.getFeeCode())).findFirst();
                    if (first.isPresent()) {
                        feeItem.setFeeiVsDictCnt(first.get().getFeeiVsDictCnt());
                    } else {
                        feeItem.setFeeiVsDictCnt(0);
                    }
                }
                labFeeItems = labFeeItems.stream().sorted(Comparator.comparing(LabFeeItem::getFeeiVsDictCnt).reversed()).collect(Collectors.toList());

            }
        }
        return Result.succ(1, "查询成功！", labFeeItems);
    }
    @Override
    public Result findFeeItemPageList(FeeItemPageParam feeItemPageParam) {
        Integer pageIndex = feeItemPageParam.getPageIndex();
        Integer pageSize = feeItemPageParam.getPageSize();
        Page<LabFeeItem> page = new Page<>();
        page.setCurrent(pageIndex);
        page.setSize(pageSize);
        MPJLambdaWrapper<LabFeeItem> lambdaQueryWrapper = new MPJLambdaWrapper<>();
        lambdaQueryWrapper.selectAll(LabFeeItem.class);
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(feeItemPageParam.getOrgId()), LabFeeItem::getOrgId, feeItemPageParam.getOrgId()).eq(LabFeeItem::getDelFlag, 0);
        if (StrUtil.isNotEmpty(feeItemPageParam.getKeyWords())) {
            lambdaQueryWrapper.and(wrapper ->
                    wrapper.like(LabFeeItem::getFeeCode, feeItemPageParam.getKeyWords())
                            .or()
                            .like(LabFeeItem::getFeeName, feeItemPageParam.getKeyWords())
                            .or()
                            .like(LabFeeItem::getInputCode, feeItemPageParam.getKeyWords())
            );
        }
        if (StrUtil.isNotEmpty(feeItemPageParam.getBarcodeNo())) {
            StringBuffer existsSql = new StringBuffer("SELECT 1 FROM LAB_FEEITEM_VS_BARCODE t2 WHERE t.FEE_CODE = t2.FEE_CODE");// AND t2.BARCODE_NO = '" + feeItemPageParam.getBarcodeNo() + "' ");
            lambdaQueryWrapper.notExists(existsSql.toString());
        }
        if (StrUtil.isNotEmpty(feeItemPageParam.getSampleTypeId()) && StrUtil.isNotEmpty(feeItemPageParam.getPurposeId())) {
            StringBuffer existsSql = new StringBuffer("SELECT 1 FROM BAC_REQPURPOSE_VS_FEEITEM t2 WHERE t2.DEL_FLAG=0 and t.FEE_CODE = t2.FEE_CODE AND t2.PURPOSE_NO = '" + feeItemPageParam.getPurposeId() + "' AND t2.SAMPLE_TYPE_CODE = '" + feeItemPageParam.getSampleTypeId() + "' ");
            lambdaQueryWrapper.notExists(existsSql.toString());
        }
        if (StrUtil.isNotEmpty(feeItemPageParam.getCompanyCode())) {
            StringBuffer existsSql = new StringBuffer("SELECT 1 FROM LAB_INSPECT_COMPANY_FEEITEM t2 WHERE t2.DEL_FLAG=0 and t.FEE_CODE = t2.FEE_CODE AND t2.COMPANY_CODE = '"+feeItemPageParam.getCompanyCode()+"'");// AND t2.BARCODE_NO = '" + feeItemPageParam.getBarcodeNo() + "' ");
            lambdaQueryWrapper.notExists(existsSql.toString());
        }
        Page<LabFeeItem> labFeeItemPage = labFeeItemMapper.selectPage(page, lambdaQueryWrapper);
        return Result.succ(1, "查询成功", labFeeItemPage);
    }

    @Override
    public Result getFeeItemListByRptGroup(FeeItemPageParam feeItemPageParam) {
        MPJLambdaWrapper<LabFeeItem> lambdaQueryWrapper = new MPJLambdaWrapper<>();

        lambdaQueryWrapper.selectAll(LabFeeItem.class)
                .innerJoin(LabFeeitemVsBarcode.class, "FB", p -> p.eq(LabFeeitemVsBarcode::getFeeCode, LabFeeItem::getFeeCode).eq(LabFeeitemVsBarcode::getDelFlag, 0))
                .innerJoin(LabRptVsBarcode.class, "RB", p -> p.eq(LabRptVsBarcode::getBarcodeNo, LabFeeitemVsBarcode::getBarcodeNo).eq(LabRptVsBarcode::getDelFlag, 0))
                .eq(LabRptVsBarcode::getRptGroup,feeItemPageParam.getRptGroup())
                .eq(LabFeeItem::getDelFlag, 0);
        if (StrUtil.isNotEmpty(feeItemPageParam.getKeyWords())) {
            lambdaQueryWrapper.and(wrapper ->
                    wrapper.like(LabFeeItem::getFeeCode, feeItemPageParam.getKeyWords())
                            .or()
                            .like(LabFeeItem::getFeeName, feeItemPageParam.getKeyWords())
                            .or()
                            .like(LabFeeItem::getInputCode, feeItemPageParam.getKeyWords())
            );
        }
        List<LabFeeItem> labFeeItems = labFeeItemMapper.selectList(lambdaQueryWrapper);

        //查询报告单元下得申请项目与报告项目关联数据
        if (StrUtil.isNotEmpty(feeItemPageParam.getRptGroup())) {
            List<String> feeItemCodes = labFeeItems.stream().map(LabFeeItem::getFeeCode).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(feeItemCodes)) {
                MPJLambdaWrapper<LabFeeitemVsItemDict> queryWrapper = new MPJLambdaWrapper<>();
                queryWrapper
                        .selectCount(LabFeeitemVsItemDict::getFeeCode, LabFeeItem::getFeeiVsDictCnt)
                        .selectAs(LabFeeitemVsItemDict::getFeeCode, LabFeeItem::getFeeCode)
                        .leftJoin(LabItemDict.class, "dic", p -> p.eq(LabItemDict::getDelFlag, 0).eq(LabItemDict::getItemNo, LabFeeitemVsItemDict::getItemNo).eq(LabItemDict::getRptGroup, LabFeeitemVsItemDict::getRptGroup))
                        .eq(LabFeeitemVsItemDict::getRptGroup, feeItemPageParam.getRptGroup())
                        .in(LabFeeitemVsItemDict::getFeeCode, feeItemCodes)
                        .eq(LabFeeitemVsItemDict::getDelFlag, 0)
                        .eq(LabItemDict::getDelFlag, 0)
                        .groupBy(LabFeeitemVsItemDict::getFeeCode);
                //根据报告单元与申请项目查询关联数据
                List<LabFeeItem> labFeeitemVsItemDictCntList = labFeeitemVsItemDictMapper.selectJoinList(LabFeeItem.class, queryWrapper);
                for (LabFeeItem feeItem : labFeeItems) {
                    Optional<LabFeeItem> first = labFeeitemVsItemDictCntList.stream().filter(cnt -> cnt.getFeeCode().equals(feeItem.getFeeCode())).findFirst();
                    if (first.isPresent()) {
                        feeItem.setFeeiVsDictCnt(first.get().getFeeiVsDictCnt());
                    } else {
                        feeItem.setFeeiVsDictCnt(0);
                    }
                }
                labFeeItems = labFeeItems.stream().sorted(Comparator.comparing(LabFeeItem::getFeeiVsDictCnt).reversed()).collect(Collectors.toList());

            }
        }
        return Result.succ(1, "查询成功！", labFeeItems);
    }


    @Override
    public Result findRptFeeItemList(FeeItemPageParam feeItemPageParam) {
        MPJLambdaWrapper<LabFeeItem> lambdaQueryWrapper = new MPJLambdaWrapper<>();

        lambdaQueryWrapper.distinct().selectAll(LabFeeItem.class)
                .leftJoin(LabReqdetail.class, "d", LabReqdetail::getFeeCode, LabFeeItem::getFeeCode)
                .leftJoin(LabMaininfo.class, "e", LabMaininfo::getReqNo, LabReqdetail::getReqNo)
        //.leftJoin(LabFeeitemVsBarcode.class, "b", LabFeeitemVsBarcode::getFeeId, LabFeeItem::getId)
        //.leftJoin(LabRptVsBarcode.class, "c", LabRptVsBarcode::getBarcodeId, LabFeeitemVsBarcode::getBarcodeId)
        ;
        lambdaQueryWrapper.eq(StrUtil.isNotEmpty(feeItemPageParam.getOrgId()), LabFeeItem::getOrgId, feeItemPageParam.getOrgId()).eq(LabFeeItem::getDelFlag, 0);

        if (StrUtil.isNotEmpty(feeItemPageParam.getRptGroup())) {
            lambdaQueryWrapper.and(wrapper -> wrapper.eq(LabMaininfo::getRptGroup, feeItemPageParam.getRptGroup()).or()
                    //.eq(LabRptVsBarcode::getRptGroupId, feeItemPageParam.getGroupId())
            );
        }
        //lambdaQueryWrapper.eq(StrUtil.isNotEmpty(feeItemPageParam.getGroupId()),  LabRptVsBarcode::getRptGroupId,feeItemPageParam.getGroupId());

        if (StrUtil.isNotEmpty(feeItemPageParam.getKeyWords())) {
            lambdaQueryWrapper.and(wrapper -> wrapper.like(LabFeeItem::getFeeCode, feeItemPageParam.getKeyWords()).or().like(LabFeeItem::getFeeName, feeItemPageParam.getKeyWords()));
        }
        List<LabFeeItem> labFeeItems = labFeeItemMapper.selectList(lambdaQueryWrapper);
        if (labFeeItems.size() > 0) {
            //查询报告单元下得申请项目与报告项目关联数据
            if (StrUtil.isNotEmpty(feeItemPageParam.getRptGroup())) {
                List<String> feeItemIds = labFeeItems.stream().map(LabFeeItem::getId).collect(Collectors.toList());
                //根据报告单元与申请项目查询关联数据
                MPJLambdaWrapper<LabFeeitemVsItemDict> queryWrapper = new MPJLambdaWrapper<>();
                queryWrapper
                        .selectCount(LabFeeitemVsItemDict::getFeeItemId, LabFeeItem::getFeeiVsDictCnt)
                        .selectAs(LabFeeitemVsItemDict::getFeeItemId, LabFeeItem::getId)
                        .eq(LabFeeitemVsItemDict::getRptGroup, feeItemPageParam.getRptGroup())
                        .in(LabFeeitemVsItemDict::getFeeItemId, feeItemIds)
                        .eq(LabFeeitemVsItemDict::getDelFlag, 0)
                        .groupBy(LabFeeitemVsItemDict::getFeeItemId);

                List<LabFeeItem> labFeeitemVsItemDictCntList = labFeeitemVsItemDictMapper.selectJoinList(LabFeeItem.class, queryWrapper);
                for (LabFeeItem feeItem : labFeeItems) {
                    Optional<LabFeeItem> first = labFeeitemVsItemDictCntList.stream().filter(cnt -> cnt.getId().equals(feeItem.getId())).findFirst();
                    if (first.isPresent()) {
                        feeItem.setFeeiVsDictCnt(first.get().getFeeiVsDictCnt());
                    } else {
                        feeItem.setFeeiVsDictCnt(0);
                    }
                }

            }
        }
        List<LabFeeItem> collect = labFeeItems.stream().sorted(Comparator.comparing(LabFeeItem::getFeeiVsDictCnt)
                .reversed()).collect(Collectors.toList());

        return Result.succ(1, "查询成功！", collect);
    }

    @Override
    public Result findFeeCodeExtenFieldsValueList(ExtenFieldsValuePageRequestDto pageParam) {
        List<LabFeeItem> labFeeItems = labFeeItemMapper.selectList(new LambdaQueryWrapper<LabFeeItem>().in(LabFeeItem::getFeeCode, Arrays.asList(pageParam.getBusRowId().split(","))).eq(LabFeeItem::getDelFlag, 0));
        Map<String,String>map=new HashMap<>();
        for (LabFeeItem labFeeItem : labFeeItems) {
            map.put(labFeeItem.getId(),labFeeItem.getFeeCode());
        }
        pageParam.setBusRowIdMap(map);
        List<Map<String,String>> deeCodeExtenFieldsValueList = sysExtenFieldsValueService.findDeeCodeExtenFieldsValueList(pageParam);
        return Result.succ(1, "查询成功！", deeCodeExtenFieldsValueList);
    }


    @Autowired
    LabFeeitemVsItemDictMapper labFeeitemVsItemDictMapper;

    /**
     * 根据分管类别查询项目信息
     *
     * @param id
     * @return
     */
    @Override
    public Result findFeeItemListByBarCodeId(String barcodeNo) {
        Assert.hasText(barcodeNo, "id must not be empty");
        MPJLambdaWrapper<LabFeeItem> mpjLambdaWrapper = new MPJLambdaWrapper<>();
        mpjLambdaWrapper
                .selectAll(LabFeeItem.class)
                .selectAs(LabFeeitemVsBarcode::getId, LabFeeItem::getVsBarCodeTypeId)
                .leftJoin(LabFeeitemVsBarcode.class, LabFeeitemVsBarcode::getFeeCode, LabFeeItem::getFeeCode)
                .eq(LabFeeitemVsBarcode::getBarcodeNo, barcodeNo)
                .eq(LabFeeItem::getDelFlag, 0)
                .eq(LabFeeitemVsBarcode::getDelFlag, 0)
                .orderByAsc(LabFeeitemVsBarcode::getSeq);
        List<LabFeeItem> labFeeItems = labFeeItemMapper.selectList(mpjLambdaWrapper);
        return Result.succ(1, "查询成功", labFeeItems);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addApplyItem(AddFeeItemParam addFeeItemParam) {
        LabFeeItem labFeeItem = new LabFeeItem();
        BeanUtil.copyProperties(addFeeItemParam, labFeeItem);
        boolean save = this.save(labFeeItem);
        if (save) {
            return Result.succ(1, "添加成功！", null);
        } else {
            return Result.fail("添加失败！");
        }
    }

    @Override
    public Result editApplyItem(AddFeeItemParam addFeeItemParam) {
        LabFeeItem labFeeItem = new LabFeeItem();
        BeanUtil.copyProperties(addFeeItemParam, labFeeItem);
        boolean b = this.updateById(labFeeItem);
        if (b) {
            return Result.succ(1, "编辑成功！", null);
        } else {
            return Result.fail("编辑失败！");
        }
    }

    @Override
    public Result deleteApplyItem(AddFeeItemParam addFeeItemParam) {
        LabFeeItem labFeeItem = new LabFeeItem();
        BeanUtil.copyProperties(addFeeItemParam, labFeeItem);
        labFeeItem.setDelFlag(1);
        boolean b = this.updateById(labFeeItem);
        if (b) {
            return Result.succ(1, "删除成功！", null);
        } else {
            return Result.fail("删除失败！");
        }
    }

    public void test() {
        DeleteJoinWrapper<LabFeeItem> eq = JoinWrappers.delete(LabFeeItem.class).eq(LabFeeItem::getFeeCode, "");
        labFeeItemMapper.deleteJoin(eq);
    }
}
